Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bypass Json string from processing #342

Closed
arun0009 opened this issue Nov 5, 2013 · 10 comments
Closed

Bypass Json string from processing #342

arun0009 opened this issue Nov 5, 2013 · 10 comments

Comments

@arun0009
Copy link

arun0009 commented Nov 5, 2013

When getting a valid JSON from database or another rest call and passing it back - jackson adds quotes to the valid json and makes it invalid.Is there any annotation or way to tell jackson that it's valid JSON and to just pass the value back?

@cowtowncoder
Copy link
Member

It sounds like you may be confused about Jackson usage here. If you have a String that contains JSON, do not use Jackson for writing it out -- all Jackson knows is that it is a String, and Strings in JSON must be enclosed in double-quotes, and have their contents escaped.
If you do not want this, simply output String as-is, and do not use Jackson for output.

But if you have such a String property as part of your object model, you can use annotation @JsonRawValue to embed it as-is, without escaping. This may be what you are looking for.

I hope this helps.

@arun0009
Copy link
Author

arun0009 commented Nov 5, 2013

I have converted the json String to JsonNode before passing it back from the below method (after Jackson upgrade to 2.2).

But - this used to work in 1.9 version of jackson (example below) and since my upgrade to 2.2 its broken and the way I fixed it is by wrapping the JSON string from another rest call in JsonNode.

@Path("/health")
@GET
@Produces(MediaType.APPLICATION_JSON)
public String getHealth(@QueryParam("app_id") String app_id) {
    URIBuilder uriBuilder = new URIBuilder(sparkpayUrl + "/ping");
    uriBuilder.addParameter("app_id", app_id);
    String url = URLDecoder.decode(uriBuilder.toString(), "UTF-8");
    logger.debug("Sparkpay Health Check url : ", url);
    String status  = restTemplate.getForObject(url, String.class);
    logger.debug("Sparkpay Health status : ", status);
    return status;
}

@cowtowncoder
Copy link
Member

Could you not just return JsonNode or POJO, and let JAX-RS do its job? Is there need to produce a String at this point.

Question is whether JAX-RS MessageBodyWriter should write String as "raw" String, or as JSON String. I don't know what the right answer is: both have their merits. But I thought that 2.2.3 should write it as raw String, not JSON String.

@arun0009
Copy link
Author

arun0009 commented Nov 5, 2013

That is what I'm returning right now - I changed the signature of the call to be

public JsonNode getHealth(@QueryParam("app_id") String app_id) {
....
...
JsonNode status = restTemplate.getForObject(url, JsonNode.class);
return status;
}

This rest service is nothing but a wrapper to another internal rest service with key management/security. This is just an example of ping we have many more operations in this API.

All I wanted was return back the json string from the rest call - I don't want to create unnecessary POJO's. As I mentioned earlier - it worked perfectly well in 1.9 but in 2.2 I had to wrap the json string with JsonNode and return it back or else jackson adds quotes to json string.

@cowtowncoder
Copy link
Member

This should not be the case, unless you are using version 2.0.0 of Jackson's JSON provider, which did have issue:

https://github.com/FasterXML/jackson-jaxrs-json-provider/issues/12

JAX-RS provider should consider String to be raw type ("untouchable"), write it exactly as-is. So I don't know what the problem could be here; unless it was a version mismatch of some sort.
Similarly other raw types (like byte[]) should be passed as-is.

One more thing to verify, just to rule out version issues: 2.3.0-rc1 is out (and official 2.3.0 in a week or two if all goes well), so would it be possible to try that version? It should be backwards compatible at API level so relatively easy to swap in.

@cowtowncoder cowtowncoder reopened this Nov 5, 2013
@arun0009
Copy link
Author

arun0009 commented Nov 5, 2013

I tried the latest version of jackson and I have the same issue when using String:

"{\n "status" : "Success",\n "pong" : 1\n}"

Maven Dependency Tree info :

[INFO] +- com.fasterxml.jackson.core:jackson-annotations:jar:2.3.0-rc1:compile
[INFO] +- com.fasterxml.jackson.core:jackson-core:jar:2.3.0-rc1:compile
[INFO] +- com.fasterxml.jackson.core:jackson-databind:jar:2.3.0-rc1:compile
[INFO] +- com.fasterxml.jackson.module:jackson-module-jaxb-annotations:jar:2.3.0-rc1:compile

If I change the api to return JsonNode, I get what I expect:

{"status":"Success","pong":1}

@cowtowncoder
Copy link
Member

Ok. That sounds like a bug then. I will need to move this, however, as it is in JAX-RS module.

@cowtowncoder
Copy link
Member

I am unfortunately unable to reproduce this, see the new issue.

@reinert
Copy link

reinert commented Mar 10, 2014

I'm experiencing this using JSONPObject. I want to pass a raw json as String but Jackson Provider escapes my String. Is there some way to tell Jackson Provider to not parse JSONPObject content?

@cowtowncoder
Copy link
Member

No; JSONPObject functionally only works for output.

It might make sense to add a new annotation to indicate "do not parse" for JAX-RS module. If so, it'd be necessary to file an issue for jackson-jaxrs-providers project.

The reason for adding a new annotation (instead of trying to reuse something that would seem useful like @JsonRawValue) is simply because JAX-RS does not give enough context to reliably know target of annotations, at least for some cases: specifically, method annotations could be viewed to have effect on return value and/or parameters.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants